package com.ctshk.rpc.order.season.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.Currency;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.ProductType;
import com.ctshk.common.enums.SystemBusinessType;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SeasonOrderManager;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.booking.enums.SupplierReserveTypeEnum;
import com.ctshk.rpc.booking.req.system.localfun.add.SupplierOrderSystemLocalFunAddReq;
import com.ctshk.rpc.booking.req.system.localfun.add.SupplierSystemOrderLocalFunAddReq;
import com.ctshk.rpc.booking.req.system.localfun.add.SupplierSystemOrderLocalFunDetailAddReq;
import com.ctshk.rpc.booking.service.ISupplierOrderService;
import com.ctshk.rpc.iotc.service.IOperateBankPreferenceService;
import com.ctshk.rpc.localfun.service.ILocalFunProductSaleRecordService;
import com.ctshk.rpc.order.localfun.req.*;
import com.ctshk.rpc.order.localfun.service.ILocalFunOrderService;
import com.ctshk.rpc.order.season.dto.SeasonOrderPayDTO;
import com.ctshk.rpc.order.season.dto.SeasonOrderTouristDataDTO;
import com.ctshk.rpc.order.season.dto.SeasonProductOrderLocalFunDTO;
import com.ctshk.rpc.order.season.entity.SeasonOrder;
import com.ctshk.rpc.order.season.entity.SeasonProductOrderLocalFun;
import com.ctshk.rpc.order.season.mapper.SeasonOrderMapper;
import com.ctshk.rpc.order.season.mapper.SeasonProductOrderLocalFunMapper;
import com.ctshk.rpc.order.season.service.ISeasonOrderTouristService;
import com.ctshk.rpc.order.season.service.ISeasonProductOrderLocalFunService;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.service.ISysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 套票-订单-当地玩乐订单 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-24
 */
@DubboService
public class SeasonProductOrderLocalFunServiceImpl extends ServiceImpl<SeasonProductOrderLocalFunMapper, SeasonProductOrderLocalFun> implements ISeasonProductOrderLocalFunService {

    @Autowired
    private SeasonProductOrderLocalFunMapper orderLocalFunMapper;

    @Autowired
    private SeasonOrderMapper seasonOrderMapper;

    @Autowired
    private ISeasonOrderTouristService seasonOrderTouristService;

    @DubboReference
    private ISupplierOrderService supplierOrderService;

    @DubboReference
    private ISysUserService iSysUserService;

    @DubboReference
    private ILocalFunProductSaleRecordService localFunProductSaleRecordService;

    @DubboReference
    private ILocalFunOrderService localFunOrderService; //当地玩乐 下单服务

    @DubboReference
    private IOperateBankPreferenceService iOperateBankPreferenceService;


    /* @MethodName: 保存本地玩乐 订单信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/25 9:42
     **/
    @Override
    public void saveLocalFunProduct(List<SeasonProductOrderLocalFunDTO> localFunList, Long userId, Long orderId) {
        LocalDateTime now = LocalDateTime.now();
        List<SeasonProductOrderLocalFun> list = localFunList.stream().map(
                localFunReq -> {
                    SeasonProductOrderLocalFun localFun = EntityUtil.copy(localFunReq, SeasonProductOrderLocalFun.class);
                    localFun.setCreateId(userId);
                    localFun.setGmtCreate(now);
                    localFun.setIsDeleted(IsDeletedCode.NO.getCode());
                    localFun.setSeasonOrderId(orderId);
                    localFun.setId(SnowflakeIdWorker.nextId());
                    return localFun;
                }
        ).collect(Collectors.toList());

        orderLocalFunMapper.insertBatchSomeColumn(list);
    }

    /* @MethodName: 获取本地玩乐订单信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/30 16:52
     **/
    @Override
    public List<SeasonProductOrderLocalFunDTO> getOrderLocalFunList(Long id) {
        List<SeasonProductOrderLocalFunDTO> resultList = EntityUtil.copyList(
                orderLocalFunMapper.selectList(
                        new QueryWrapper<SeasonProductOrderLocalFun>().lambda()
                                .eq(SeasonProductOrderLocalFun::getSeasonOrderId, id)
                                .eq(SeasonProductOrderLocalFun::getIsDeleted, IsDeletedCode.NO.getCode())

                ), SeasonProductOrderLocalFunDTO.class);

        return resultList;
    }


    @Override
    public void playSupplierOrder(Long orderId, TokenUser tokenUser) {
        SeasonOrder seasonOrder = getSeasonOrderById(orderId);
        //旅客信息
        List<SeasonOrderTouristDataDTO> touristList = seasonOrderTouristService.getTouristList(orderId);
        //是否是同一供应商（判读条件 主订单的 供应商id(就是负责人的部门id) 是否与机票一直）
        boolean ifEqualSupplier = true;
        //获取当前用户信息
        UserDTO user = iSysUserService.getUser(new UserDTO().setId(tokenUser.getId()));
        UserDTO chargeDto = iSysUserService.getUser(new UserDTO().setId(seasonOrder.getChargeUserId()));
        Long deptId = chargeDto.getDeptId();
        List<SeasonProductOrderLocalFunDTO> localFunList = getOrderLocalFunList(orderId);
        if (!CollectionUtils.isEmpty(localFunList)) {
            SeasonProductOrderLocalFunDTO localDto1 = localFunList.get(0);
            if (!localDto1.getSupplierId().equals(deptId)) {
                ifEqualSupplier = false;
            }
            playSupplierLocalFunOrder(seasonOrder, touristList, localFunList, localDto1.getSupplierId(), localDto1.getSupplierName(), user);
            if (!ifEqualSupplier) {//不是同一供应商 再次发起供应商预订单 只是供应商id 不同
                String depName = chargeDto.getDept();
                playSupplierLocalFunOrder(seasonOrder, touristList, localFunList, deptId, depName, user);
            }
        }
    }


    /* @MethodName: 本地玩乐 释放库存
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/13 17:59
     **/
    @Override
    public void backStock(Long orderId, Long userId) {
        List<SeasonProductOrderLocalFunDTO> list = getOrderLocalFunList(orderId);
        if (!CollectionUtils.isEmpty(list)) {
            SeasonProductOrderLocalFunDTO localFun = list.get(0);
            localFunProductSaleRecordService.backToStock(orderId, localFun.getProductId(), localFun.getAttr1Id(), localFun.getAttr2Id(), localFun.getNumber(), userId);
        }
    }


    /* @MethodName: 动态套票 下当地玩乐 单项单 生成对应的订单号
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/13 19:04
     **/
    @Override
    public void playLocalFunOrder(Long orderId, TokenUser user, List<SeasonOrderPayDTO> payList, List<SeasonOrderTouristDataDTO> touristList) {
        SeasonOrder seasonOrder = getSeasonOrderById(orderId);
        UserDTO uDto = iSysUserService.getUser(new UserDTO().setId(user.getId()));
        List<SeasonProductOrderLocalFunDTO> list = getOrderLocalFunList(orderId);
        if (!CollectionUtils.isEmpty(list)) {
            SeasonProductOrderLocalFunDTO dto = list.stream().findFirst().get();
            LocalFunDyTicketPayOrderReq localReq = new LocalFunDyTicketPayOrderReq();
            LocalFunAddCheckOrderReq checkOrderReq = new LocalFunAddCheckOrderReq();
            LocalFunOrderInputCheckReq checkReq = new LocalFunOrderInputCheckReq();

            checkReq.setProductId(dto.getProductId());
            checkReq.setSurname(seasonOrder.getSurname());
            checkReq.setName(seasonOrder.getName());
            checkReq.setContactName(seasonOrder.getContactName());
            checkReq.setContactMobile(seasonOrder.getContactMobile());
            checkReq.setContactMobileAreaCodeId(seasonOrder.getContactMobileAreaCodeId());
            checkReq.setAppellation(seasonOrder.getAppellation());
            checkReq.setContactMobileAreaCode(seasonOrder.getContactMobileAreaCode());
            checkReq.setContactEmail(seasonOrder.getContactEmail());
            checkReq.setIntegral(seasonOrder.getIntegral());
            checkReq.setMemberId(seasonOrder.getMemberId());
            checkReq.setIntegralDeduction(seasonOrder.getIntegralDeduction());
            checkReq.setRemark(seasonOrder.getRemark());
            checkReq.setNum(dto.getNumber());
            checkReq.setAttr1Id(dto.getAttr1Id());
            checkReq.setAttr2Id(dto.getAttr2Id());
            checkReq.setUseDate(dto.getProductDate());
            checkOrderReq.setLocalFunOrderInputCheckReq(checkReq);

            List<LocalFunOrderTouristInputCheckReq> touristInfos = new LinkedList<>();
            for (SeasonOrderTouristDataDTO tourist : touristList) {
                LocalFunOrderTouristInputCheckReq touristReq = new LocalFunOrderTouristInputCheckReq();
                touristReq.setSurname(tourist.getSurname());
                touristReq.setName(tourist.getName());
                touristReq.setTouristName(tourist.getTouristName());
                touristReq.setBirthday(tourist.getBirthday());
                touristReq.setCertificatesTypeId(tourist.getCertificatesTypeId());
                touristReq.setCertificatesType(tourist.getCertificatesType());
                touristReq.setAppellation(tourist.getAppellation());
                touristReq.setCertificatesNumber(tourist.getCertificatesNumber());
                touristReq.setVaildDate(tourist.getVaildDate().toLocalDate());
                touristInfos.add(touristReq);
            }
            checkOrderReq.setTouristInfos(touristInfos);

            PayOrderReq orderReq = new PayOrderReq();
            orderReq.setAttrId1(dto.getAttr1Id());
            orderReq.setAttrId2(dto.getAttr2Id());
            List<LocalFunPayOrderCollectionReq> reqList = new LinkedList<>();
            for (SeasonOrderPayDTO pay : payList) {
                LocalFunPayOrderCollectionReq collectionReq = new LocalFunPayOrderCollectionReq();
                collectionReq.setCollectionAmount(seasonOrder.getReceivableAmount());
                collectionReq.setCollectionNumber(pay.getCollectionNumber());
                collectionReq.setCurrency(pay.getCurrency());
                collectionReq.setCurrencyId(pay.getCurrencyId());
                collectionReq.setCollectionAmount(pay.getCollectionAmount());
                collectionReq.setCollectionWayId(pay.getCollectionWayId());
                collectionReq.setCollectionWay(pay.getCollectionWay());
                collectionReq.setIsPos(pay.getIsPos());
                collectionReq.setPayer(pay.getPayer());
                collectionReq.setRemark(pay.getRemark());
                collectionReq.setCollectionCertificateJson(pay.getCollectionCertificateJson());
                collectionReq.setIsUnionpayDiscount(pay.getIsUnionpayDiscount());
                collectionReq.setUnionpayDiscountId(pay.getUnionpayDiscountId());
                reqList.add(collectionReq);
            }
            orderReq.setReqList(reqList);
            localReq.setTokenUser(user);
            localReq.setLocalFunAddCheckOrderReq(checkOrderReq);
            localReq.setPayOrderReq(orderReq);
            localReq.setDeptId(uDto.getDeptId());//套票负责人id
            localReq.setDeptName(uDto.getDept());
            Result<Long> result = localFunOrderService.payOrder(localReq);
            int code = result.getCode();
            if (0 == code) {//表示成功
                Long localOrderId = result.getData();//本地玩乐的订单id 需要保存到数据库
                UpdateWrapper<SeasonProductOrderLocalFun> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().eq(SeasonProductOrderLocalFun::getProductId, dto.getProductId());
                updateWrapper.lambda().eq(SeasonProductOrderLocalFun::getIsDeleted, IsDeletedCode.NO.getCode());
                updateWrapper.lambda().eq(SeasonProductOrderLocalFun::getSeasonOrderId, orderId);
                updateWrapper.lambda().set(SeasonProductOrderLocalFun::getOrderId, localOrderId);
                updateWrapper.lambda().set(SeasonProductOrderLocalFun::getModifiedId, user.getId());
                updateWrapper.lambda().set(SeasonProductOrderLocalFun::getGmtModified, LocalDateTime.now());
                updateWrapper.lambda().set(SeasonProductOrderLocalFun::getScheduledStatus, SeasonOrderManager.AFFIRM_NO);//未确认
                orderLocalFunMapper.update(null, updateWrapper);

            }
        }
    }


    /* @MethodName: 本地玩乐 下供应商 预订单
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/12 15:23
     **/
    private void playSupplierLocalFunOrder(SeasonOrder seasonOrder, List<SeasonOrderTouristDataDTO> touristList, List<SeasonProductOrderLocalFunDTO> localFunList, Long supplierId, String supplierName, UserDTO user) {
        SupplierOrderSystemLocalFunAddReq funAddReq = new SupplierOrderSystemLocalFunAddReq();
        SeasonProductOrderLocalFunDTO funDTO1 = localFunList.get(0);
        //订单类型
        funAddReq.setOrderType(1);
        //供应商ID不能为空
        funAddReq.setSupplierId(supplierId);
        //供应商名称
        funAddReq.setSupplierName(supplierName);
        //供应商订单类型不能为空 1:普通订单,2:内部挂账订单
        funAddReq.setSupplierOrderType("2");
        //供应商销售编号/部门ID(根据'供应商订单编号'显示，1：供应商销售编号，2：部门ID)
        funAddReq.setOriginalSaleNumber(String.valueOf(user.getDeptId()));
        //业务类型不能为空
        funAddReq.setBusinessType(SystemBusinessType.LOCAL_FUN.getCode());
        //预订类型
        funAddReq.setReserveTypeId(SupplierReserveTypeEnum.LOCAL_FUN.getId());
        //产品类型
        funAddReq.setProductType(ProductType.MANUAL_ENTRY.getCode());
        //资源所属部门ID
        funAddReq.setDepartmentId(user.getDeptId());
        //资源所属部门
        funAddReq.setDepartment(user.getDept());
        //销售单号
        funAddReq.setSaleNumber(seasonOrder.getOrderNumber());
        //产品编号(通用)
        funAddReq.setProductNumber(String.valueOf(funDTO1.getProductId()));
        //产品名称
        funAddReq.setProductNumber(seasonOrder.getProductName());
        //总金额
        funAddReq.setTotalFee(seasonOrder.getOrderAmount());
        //币种id
        funAddReq.setCurrencyId(Currency.HKD.getCode());
        //币种
        funAddReq.setCurrency(Currency.HKD.getCurrency());
        //应付金额不能为空
        funAddReq.setPayableAmount(seasonOrder.getReceivableAmount());
        //付款类型ID不能为空
        //hotelReq.setPayTypeId();
        List<SupplierSystemOrderLocalFunAddReq> localFunAddReqList = new LinkedList<>();

        for (SeasonProductOrderLocalFunDTO funDTO : localFunList) {
            SupplierSystemOrderLocalFunAddReq localFunAddReq = new SupplierSystemOrderLocalFunAddReq();
            localFunAddReq.setOrderId(seasonOrder.getId());
            localFunAddReq.setSuitablePeople(funDTO.getApplicableCrowdName());
            List<SupplierSystemOrderLocalFunDetailAddReq> funDetailAddReqList = new LinkedList<>();
            for (SeasonOrderTouristDataDTO dataDTO : touristList) {
                SupplierSystemOrderLocalFunDetailAddReq funDetailAddReq = new SupplierSystemOrderLocalFunDetailAddReq();
                funDetailAddReq.setOrderId(seasonOrder.getId());
                funDetailAddReq.setProductName(funDTO.getSpecificationName());
                funDetailAddReq.setPassengerName(dataDTO.getTouristName());
                funDetailAddReq.setNumber(funDTO.getNumber());
                funDetailAddReqList.add(funDetailAddReq);
            }
            localFunAddReq.setSupplierSystemOrderLocalFunDetailAddReqList(funDetailAddReqList);
            localFunAddReqList.add(localFunAddReq);
        }
        funAddReq.setSupplierSystemOrderLocalFunAddReqList(localFunAddReqList);
        supplierOrderService.addSystemLocalFun(funAddReq, user.getId());
    }

    /* @MethodName: 动态套票 下各自订单后 确认对应状态
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/14 10:57
     **/
    @Override
    public void changeAffirmState(Long orderId, Integer isAffirm) {
        UpdateWrapper<SeasonProductOrderLocalFun> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SeasonProductOrderLocalFun::getOrderId, orderId);
        updateWrapper.lambda().set(SeasonProductOrderLocalFun::getScheduledStatus, isAffirm);
        orderLocalFunMapper.update(null, updateWrapper);
    }

    /* @MethodName: 退款状态
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/20 10:25
     **/
    @Override
    public void changeCancelOrderState(Long orderId, Integer cancelStatus) {
        UpdateWrapper<SeasonProductOrderLocalFun> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SeasonProductOrderLocalFun::getOrderId, orderId);
        updateWrapper.lambda().set(SeasonProductOrderLocalFun::getCancelStatus, cancelStatus);
        orderLocalFunMapper.update(null, updateWrapper);
    }

    /* @MethodName: 下本地玩乐的 订单  以内部挂账形式
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/20 17:54
     **/
    @Override
    public void playInternalOrder(Long orderId, TokenUser user, List<SeasonOrderTouristDataDTO> touristList) {
        LocalFunFixTicketPayOrderReq payOrderReq = new LocalFunFixTicketPayOrderReq();
        Result<Long> result = localFunOrderService.payFixOrder(payOrderReq);
        int code = result.getCode();
        if (0 == code) {//表示成功
            Long localOrderId = result.getData();//本地玩乐的订单id 需要保存到数据库
            UpdateWrapper<SeasonProductOrderLocalFun> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(SeasonProductOrderLocalFun::getIsDeleted, IsDeletedCode.NO.getCode());
            updateWrapper.lambda().eq(SeasonProductOrderLocalFun::getSeasonOrderId, orderId);
            updateWrapper.lambda().set(SeasonProductOrderLocalFun::getOrderId, localOrderId);
            updateWrapper.lambda().set(SeasonProductOrderLocalFun::getModifiedId, user.getId());
            updateWrapper.lambda().set(SeasonProductOrderLocalFun::getGmtModified, LocalDateTime.now());
            updateWrapper.lambda().set(SeasonProductOrderLocalFun::getScheduledStatus, SeasonOrderManager.AFFIRM_NO);//未确认
            orderLocalFunMapper.update(null, updateWrapper);

        }
    }


    /* @MethodName: 获取对应的价格（动态套票订单 单项产品的价格）
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/20 18:07
     **/
    public BigDecimal getParallelismPrice(BigDecimal seasonAmount, BigDecimal singleAmount, BigDecimal payAmount) {
        return null;
    }


    public SeasonOrder getSeasonOrderById(Long id) {
        return seasonOrderMapper.selectById(id);
    }
}
